﻿using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.ComponentModel;
using GloboTicketAdmin.Mobile.Services;
using GloboTicketAdmin.Mobile.Models;
using GloboTicketAdmin.Mobile.ViewModels.Base;
using CommunityToolkit.Mvvm.Messaging;
using GloboTicketAdmin.Mobile.Messages;

namespace GloboTicketAdmin.Mobile.ViewModels
{
    public partial class EventDetailViewModel : ViewModelBase, IQueryAttributable
    {
        [ObservableProperty]
        private Guid _id;

        [ObservableProperty]
        private string _name = default!;

        [ObservableProperty]
        private double _price;

        [ObservableProperty]
        private string _imageUrl;

        [ObservableProperty]
        [NotifyCanExecuteChangedFor(nameof(CancelEventCommand))]
        private EventStatusEnum _eventStatus;

        [ObservableProperty]
        [NotifyCanExecuteChangedFor(nameof(CancelEventCommand))]
        private DateTime _date = DateTime.Now;

        [ObservableProperty]
        private string _description;

        [ObservableProperty]
        private List<string> _artists = new();

        [ObservableProperty]
        private CategoryViewModel _category = new();

        [ObservableProperty]
        [NotifyPropertyChangedFor(nameof(ShowThumbnailImage))]
        private bool _showLargerImage;

        public bool ShowThumbnailImage => !ShowLargerImage;

        [RelayCommand(CanExecute = nameof(CanCancelEvent))]
        private async Task CancelEvent()
        {
            if (await _eventService.UpdateStatus(Id, EventStatusModel.Cancelled))
            {
                EventStatus = EventStatusEnum.Cancelled;
            }
        }

        private bool CanCancelEvent() => EventStatus != EventStatusEnum.Cancelled && Date.AddHours(-4) > DateTime.Now;

        [RelayCommand]
        private async Task DeleteEvent()
        {
            if (await _dialogService.Ask("Confirm Delete", "Are you sure you want to delete this event?"))
            {
                if (await _eventService.DeleteEvent(Id))
                {
                    WeakReferenceMessenger.Default.Send(new EventDeletedMessage(Id));
                    await _navigationService.GoToOverview();
                }
            }
               
        }

        [RelayCommand]
        private async Task NavigateToEditEvent()
        {
            var detailModel = MapToEventModel(this);
            await _navigationService.GoToEditEvent(detailModel);
        }

        private EventModel MapToEventModel(EventDetailViewModel eventDetailViewModel)
        {
            var eventModel = new EventModel
            {
                Id = eventDetailViewModel.Id,
                Name = eventDetailViewModel.Name,
                Price = eventDetailViewModel.Price,
                ImageUrl = eventDetailViewModel.ImageUrl,
                EventStatus = (EventStatusEnum)(int)eventDetailViewModel.EventStatus,
                CreateTime = eventDetailViewModel.Date,
                Description = eventDetailViewModel.Description,
                Artists = eventDetailViewModel.Artists,
                Category = new CategoryModel
                {
                    Id = eventDetailViewModel.Category.Id,
                    Name = eventDetailViewModel.Category.Name
                }
            };
            return eventModel;
        }

        private readonly IEventService _eventService;
        private readonly INavigationService _navigationService;
        private readonly IDialogService _dialogService;

        public EventDetailViewModel(IEventService eventService, INavigationService navigationService, IDialogService dialogService)
        {
            _eventService = eventService;
            _navigationService = navigationService;
            _dialogService = dialogService;
        }

        public override async Task LoadAsync()
        {
            await Loading(
                async () =>
                {
                    //CancelEventCommand.NotifyCanExecuteChanged();
                    if (Id != Guid.Empty)
                    {
                        await GetEvent(Id);
                    }
                }
                );
        }

        private async Task GetEvent(Guid id)
        {
            //await Task.Delay(3000); // Simulate a short delay for better UX
            var @event = await _eventService.GetEvent(id);

            if (@event is not null)
            {
                MapEventData(@event);
            }
        }

        private void MapEventData(EventModel @event)
        {
            Id = @event.Id;
            Name = @event.Name;
            Price = @event.Price;
            ImageUrl = @event.ImageUrl;
            EventStatus = (EventStatusEnum)@event.EventStatus;
            Date = @event.CreateTime;
            Description = @event.Description;
            Artists = @event.Artists;
            Category = new CategoryViewModel
            {
                Id = @event.Category.Id,
                Name = @event.Category.Name
            };
        }

        public async void ApplyQueryAttributes(IDictionary<string, object> query)
        {
            if (query.Count>0)
            {
                var eventId = query["EventId"].ToString();
                if (Guid.TryParse(eventId, out var selectedId))
                {
                    Id = selectedId;
                    //await GetEvent(Id);
                }
            }
        }
    }

}
